#ifndef __LYRICS_INC__
#define __LYRICS_INC__

#define LINESLIMIT 100
#define SYLLABLESLIMIT 20

//Syllable has the basic information of a lyrics syllable
TYPE syllable
  int activation_time=0;
  int deactivation_time=0;
  int tone=0;
  int activated=0;
  string text="";
End;

//Line type has the basic information of a line, as well as the first syllable of a line.
TYPE lyrics_line
  int appearance_time=0;
  int activation_time=0;
  int deactivation_time=0;
  int pid=0;
  int width=0;
  int visibility=0;
  string line_text="";
  syllable syllables[SYLLABLESLIMIT];
End;

//Song type includes the basic information for the song, as well as
//the pointer to the first line of lyrics.
TYPE song
  int bpm=0;
  int fd=0;
  int gap=0;
  int relative=0;
  int videogap=0;
  string artist="";
  string charset="";
  string title="";
  string cover="";
  string bckgrnd="";
  string video_file="";
  string music_file="";
  string license="";
  string url="";
  lyrics_line lines[LINESLIMIT];
End;

//Read the header for the description info. Leave the file descriptor
//pointer where the lyrics start.
Function parse_file(string filename, song pointer kar)
Private
  int pos=0, n=0, retval=0;
  string line;

Begin
  //Open the description file
  kar.fd = fopen(filename, O_READ);
  if(!kar.fd)
    say("descriptor file '"+filename+"' couldn't be opened");
    return -1;
  End;

  // Determine the charset of the file (in case of failure, will default to a
  // wrong value most of the times)
  kar.charset = determine_charset(filename);

  //Read the file, and fill the kar struct
  while(!feof(kar.fd))
    line = fgets(kar.fd);
    if((pos = find(line, "#MP3:")) != -1)
      kar.music_file = substr(line, pos+len("#MP3:"));
    #ifndef NO_SMPEG
      elif((pos = find(line, "#VIDEO:")) != -1)
        kar.video_file = substr(line, pos+len("#VIDEO:"));
    #endif
    elif((pos = find(line, "#TITLE:")) != -1)
      kar.title = substr(line, pos+len("#TITLE:"));
    elif((pos = find(line, "#ARTIST:")) != -1)
      kar.artist = substr(line, pos+len("#ARTIST:"));
    elif((pos = find(line, "#COVER:")) != -1)
      kar.cover = substr(line, pos+len("#COVER:"));
    elif((pos = find(line, "#BACKGROUND:")) != -1)
      kar.bckgrnd = substr(line, pos+len("#BACKGROUND:"));
    elif((pos = find(line, "#GAP:")) != -1)
      kar.gap = atoi(substr(line, pos+len("#GAP:")))/10;
    #ifndef NO_SMPEG
      elif((pos = find(line, "#VIDEOGAP:")) != -1)
        kar.videogap = atoi(substr(line, pos+len("#VIDEOGAP:")))/10;
    #endif
    elif((pos = find(line, "#BPM:")) != -1)
      kar.bpm = atoi(substr(line, pos+len("#BPM:")));
    elif((pos = find(line, "#RELATIVE:")) != -1)
      kar.relative = substr(line, pos+len("#RELATIVE:"));
    elif((pos = find(line, "#LICENSE:")) != -1)
      kar.license = substr(line, pos+len("#LICENSE:"));
    elif((pos = find(line, "#URL:")) != -1)
      kar.artist = substr(line, pos+len("#URL:"));
    end;
    if(line[0] == "#")
      n++;
    end;
  end;

  //TODO: Review
  if(kar.gap != 0 && kar.videogap != 0)
    kar.videogap += kar.gap;
  end;

  kar.artist = iconv(kar.charset, "UTF8//TRANSLIT", kar.artist);
  kar.title  = iconv(kar.charset, "UTF8//TRANSLIT", kar.title );

  //Set the read buffer at the beginning of the lyrics, don't close the file
  //descriptor
  fseek(kar.fd, 0, SEEK_SET);
  for(n; n>0; n--)
    fgets(kar.fd);
  end;  
End;

//Reads a whole file and fills all the data associated to it
Function int ReadBeatFile(song pointer kar)
Private
  int retval=0, i=0, j=0, deact_time=0;

Begin
  //Get the song lyrics
  while(retval != -2 && i < lineslimit )
    while(retval != -1 && j < syllableslimit )
      retval = ReadBeat(kar.bpm, kar.fd,
                &kar.lines[i].syllables[j].activation_time,
                &kar.lines[i].syllables[j].deactivation_time,
                &kar.lines[i].syllables[j].tone,
                kar.gap, kar.videogap,
                &kar.lines[i].syllables[j].text);
      kar.lines[i].syllables[j].text = iconv (kar.charset, "UTF8//TRANSLIT",
                kar.lines[i].syllables[j].text);
      //This way, we also fill the line text
      kar.lines[i].line_text += kar.lines[i].syllables[j].text;
        
      //Deact_time holds the maximum deactivation time in a verse
      if(deact_time < kar.lines[i].syllables[j].deactivation_time)
        deact_time = kar.lines[i].syllables[j].deactivation_time;
      end;
      j++;
    end;

    kar.lines[i].activation_time = kar.lines[i].syllables[0].activation_time;
    kar.lines[i].deactivation_time = deact_time;
    if(i >= 1)
      kar.lines[i].appearance_time = kar.lines[i-1].activation_time;
    else
      //You've got a 3 seconds lapse between the first line appears and the
      //song starts
      kar.lines[0].appearance_time = kar.lines[0].activation_time - 300;
    end;
    retval=0; j=0; i++;
  end
End;

//Reads the data for a "beat", usually just a syllable
Function int ReadBeat(int bpm, int fd, int pointer time,
            int pointer deact_time, int pointer tone, int gap, int videogap,
            string pointer lyrics)
Private
  int pos=0, t_in_beats=0;
  string line="";

Begin
  if(!fd || desc_file_finished == 1)
    return -2;
  end;

  line = fgets(fd);
  //Look for the file finish descriptor or for the last line in the file
  if(line[0] == "E" || feof(fd))
    desc_file_finished = 1;
    return -2;
  end;

  if(line[0] == "-" || len(line) == 0)
    *time = atoi(_trim(line))*10;
    return -1;
  end;

  pos = find(line, " ");
  line = substr(line, pos+1);
  pos = find(line, " ");
  //What we get is a beat, not an absolut time, gotta convert it
  t_in_beats = atoi(substr(line, 0, pos));
  *time = beat_2_csec(t_in_beats, bpm) + gap + videogap;
  line = substr(line, pos+1);
  pos = find(line, " ");
  t_in_beats += atoi(substr(line, 0, pos));
  *deact_time = beat_2_csec(t_in_beats, bpm) + gap + videogap;
  line = substr(line, pos+1);
  pos = find(line, " ");
  *tone = atoi(substr(line, 0, pos));
  line = substr(line, pos+1);
  *lyrics = substr(line, 0, len(line));
  
  return 0;
end;

#endif
